local L = LibStub("AceLocale-3.0"):GetLocale("AzCastBarOptions")
local FormatTime = AzCastBar.FormatTime;
local GetLootRollTimeLeft = GetLootRollTimeLeft;
local gtt = GameTooltip;

local b = AzCastBar.CreateBar("Button");
local UpdateRollBars;
local rolls = {};

-- Cleanup Blizz Roll Windows
UIParent:UnregisterEvent("START_LOOT_ROLL");
for i = 1, NUM_GROUP_LOOT_FRAMES do
	_G["GroupLootFrame"..i]:UnregisterAllEvents();
end
GroupLootFrame_OpenNewFrame = nil;
GroupLootFrame_OnShow = nil;
GroupLootFrame_OnHide = nil;
GroupLootFrame_OnEvent = nil;
GroupLootFrame_OnUpdate = nil;

--------------------------------------------------------------------------------------------------------
--                                               Events                                               --
--------------------------------------------------------------------------------------------------------

-- OnUpdate
local function OnUpdate(self,elapsed)
	local roll = self.roll;
	-- Normal Progression
	if (not self.fadeTime) then
		self.timeLeft = (GetLootRollTimeLeft(roll.id) / 1000);
		if (self.timeLeft > roll.time) then
			self.timeLeft = 0;
		end
		self.status:SetValue(self.timeLeft);
		self.time:SetText(FormatTime(self.timeLeft)..(b.cfg.showTotalTime and " / "..FormatTime(roll.time) or ""));
		if (self.timeLeft == 0) then
			self.fadeTime = b.cfg.fadeTime
		end
	-- FadeOut
	elseif (self.fadeElapsed <= self.fadeTime) then
		self.fadeElapsed = (self.fadeElapsed + elapsed);
		self:SetAlpha(b.cfg.alpha - self.fadeElapsed / self.fadeTime * b.cfg.alpha);
	else
		tremove(rolls,self.index);
		UpdateRollBars();
	end
	-- Change Cursor Icon
	if (gtt:IsOwned(self)) then
		if (IsModifiedClick("DRESSUP")) then
			ShowInspectCursor();
		else
			ResetCursor();
		end
	end
end

-- OnClick
local function OnClick(self,button,down)
	if (button == "LeftButton") then
		HandleModifiedItemClick(GetLootRollItemLink(self.roll.id));
	elseif (button == "RightButton") then
		RollOnLoot(self.roll.id,0);
	end
end

-- OnEnter
local function OnEnter(self)
	gtt:SetOwner(self,true and "ANCHOR_RIGHT" or "ANCHOR_LEFT");
	gtt:SetLootRollItem(self.roll.id);
end

-- HideGTT
local function OnLeave(self)
	gtt:Hide();
	ResetCursor();
end

-- OnEvent
local function OnEvent(self,event,rollId,rollTime,...)
	-- New Roll
	if (event == "START_LOOT_ROLL") then
		tinsert(rolls,{ id = rollId, time = rollTime / 1000 });
		UpdateRollBars();
	-- Roll Canceled
	elseif (event == "CANCEL_LOOT_ROLL") then
		for index, table in ipairs(rolls) do
			if (table.id == rollId) then
				tremove(rolls,index);
				StaticPopup_Hide("CONFIRM_LOOT_ROLL",rollId);
				UpdateRollBars();
				break;
			end
		end
	end
end

--------------------------------------------------------------------------------------------------------
--                                                Code                                                --
--------------------------------------------------------------------------------------------------------

-- RollButtons OnClick
local function RollButtons_OnClick(self,button,down)
	RollOnLoot(self:GetParent().roll.id,self.type);
end

-- RollButtons OnClick
local function RollButtons_OnEnter(self)
	gtt:SetOwner(self,"ANCHOR_RIGHT");
	gtt:SetText(self.type == 1 and L["Need"] or L["Greed"]);
end

-- ConfigureBar
local function ConfigureBar(bar,id)
	-- Need Button
	bar.need = CreateFrame("Button",nil,bar);
	bar.need:RegisterForClicks("LeftButtonUp");
	bar.need:SetWidth(32);
	bar.need:SetHeight(32);
	bar.need:SetPoint("TOPLEFT",bar,"TOPRIGHT",6,2);
	bar.need:SetNormalTexture("Interface\\Buttons\\UI-GroupLoot-Dice-Up");
	bar.need:SetHighlightTexture("Interface\\Buttons\\UI-GroupLoot-Dice-Highlight");
	bar.need:SetPushedTexture("Interface\\Buttons\\UI-GroupLoot-Dice-Down");
	bar.need:SetScript("OnClick",RollButtons_OnClick);
	bar.need:SetScript("OnEnter",RollButtons_OnEnter);
	bar.need:SetScript("OnLeave",OnLeave);
	bar.need.type = 1;
	-- Greed Button
	bar.greed = CreateFrame("Button",nil,bar);
	bar.greed:RegisterForClicks("LeftButtonUp");
	bar.greed:SetWidth(32);
	bar.greed:SetHeight(32);
	bar.greed:SetPoint("LEFT",bar.need,"RIGHT",2,0);
	bar.greed:SetNormalTexture("Interface\\Buttons\\UI-GroupLoot-Coin-Up");
	bar.greed:SetHighlightTexture("Interface\\Buttons\\UI-GroupLoot-Coin-Highlight");
	bar.greed:SetPushedTexture("Interface\\Buttons\\UI-GroupLoot-Coin-Down");
	bar.greed:SetScript("OnClick",RollButtons_OnClick);
	bar.greed:SetScript("OnEnter",RollButtons_OnEnter);
	bar.greed:SetScript("OnLeave",OnLeave);
	bar.greed.type = 2;
	-- Other
	bar:EnableMouse(1);
	bar:RegisterForClicks("LeftButtonUp","RightButtonUp");
	bar:SetScript("OnUpdate",OnUpdate);
	bar:SetScript("OnClick",OnClick);
	bar:SetScript("OnEnter",OnEnter);
	bar:SetScript("OnLeave",OnLeave);
	tinsert(b.bars,bar);
	AzCastBar.ApplyBarSettingsSpecific(b,id);
	return bar;
end

-- UpdateBars
UpdateRollBars = function()
	local bar;
	local texture, name, count, quality, bindOnPickUp
	local color;
	-- Loop Rolls
	for index, table in ipairs(rolls) do
		bar = b.bars[index] or ConfigureBar(AzCastBar.CreateBar("Button"),index);
		texture, name, count, quality, bindOnPickUp = GetLootRollItemInfo(table.id);
		color = ITEM_QUALITY_COLORS[quality];
		bar.status:SetMinMaxValues(0,table.time);
		bar.status:SetStatusBarColor(color.r,color.g,color.b);
		bar.name:SetText((bindOnPickUp and "|cffffff00BoP|r " or "")..tostring(name)..(count and count > 1 and " ("..count..")" or ""));
		bar.icon:SetTexture(texture);
		bar.roll = table;
		bar.index = index;
		bar.fadeTime = nil;
		bar.fadeElapsed = 0;
		bar:SetAlpha(b.cfg.alpha);
		bar:Show();
	end
	-- Hide Remaining
	for i = #rolls + 1, #b.bars do
		b.bars[i]:Hide();
	end
	-- Update Tooltip
	local mouseFocus = GetMouseFocus();
	if (mouseFocus) and (gtt:IsOwned(mouseFocus)) then
		for i = 1, #b.bars do
			if (mouseFocus == b.bars[i]) then
				OnEnter(mouseFocus);
				break;
			end
		end
	end
end

--------------------------------------------------------------------------------------------------------
--                                              Finalize                                              --
--------------------------------------------------------------------------------------------------------

-- OnConfigChanged
function b:OnConfigChanged(cfg,barId)
	if (barId == 1) and (cfg.enabled) then
		UpdateRollBars();
	end
end

-- Init AzCastBar Entry
b.token = L["LootRolls"];
b.bars = {};
b:ClearAllPoints();
b:SetPoint("CENTER");
ConfigureBar(b,1);
tinsert(AzCastBar.frames,b);
-- Events
b:RegisterEvent("START_LOOT_ROLL");
b:RegisterEvent("CANCEL_LOOT_ROLL");
b:SetScript("OnEvent",OnEvent);